//
//  UIImage+DYNinePatch.m
//  AFNetworking
//
//  Created by 李松芮 on 2018/9/6.
//

#import "UIImage+DYNinePatch.h"

typedef NS_OPTIONS(NSUInteger, DYNinePatchStripType) {
    DYNinePatchStripTypeTop = 1 << 0,
    DYNinePatchStripTypeLeft = 1 << 1,
    DYNinePatchStripTypeBottom = 1 << 2,
    DYNinePatchStripTypeRight = 1 << 3,
    DYNinePatchStripTypeAll = DYNinePatchStripTypeTop | DYNinePatchStripTypeLeft | DYNinePatchStripTypeBottom | DYNinePatchStripTypeRight
};

typedef struct {
    uint8_t r;
    uint8_t g;
    uint8_t b;
    uint8_t a;
} DYNinePatchRGBAPixel;

static inline BOOL IsBlackPixel(DYNinePatchRGBAPixel pixel)
{
    if (pixel.r == 0 && pixel.g == 0 && pixel.b == 0 && pixel.a == 255) {
        return YES;
    }
    return NO;
}

@implementation UIImage (DYNinePatch)

#pragma mark - 黑边搜索
- (BOOL)searchBlackStrip:(DYNinePatchStripType)areaType resizableInset:(UIEdgeInsets *)resizableInset contentInset:(UIEdgeInsets *)contentInset cropFrame:(CGRect *)cropFrame
{
    CGSize mySize = self.size;
    if ((mySize.width > 0.0f) && (mySize.height > 0.0f) && resizableInset) {
        CGFloat top = 0, left = 0, bottom = 0, right = 0;
        CGFloat c_top = 0, c_left = 0, c_bottom = 0, c_right = 0;
        
        int colorWidth = 4; // RGBA
        CGImageRef cgImage = [self CGImage];
        NSUInteger width = CGImageGetWidth(cgImage);
        NSUInteger height = CGImageGetHeight(cgImage);
        NSUInteger bytesPerRow = width * colorWidth;
        NSUInteger bitsPerComponent = 8;
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        UInt8 *pixelByteData = malloc(width * height * colorWidth);
        
        
        CGContextRef context = CGBitmapContextCreate((void *)pixelByteData,
                                                     width,
                                                     height,
                                                     bitsPerComponent,
                                                     bytesPerRow,
                                                     colorSpace,
                                                     kCGImageAlphaPremultipliedLast);
        CGContextClearRect(context, CGRectMake(0, 0, width, height));
        CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgImage);
        DYNinePatchRGBAPixel *pixelData = (DYNinePatchRGBAPixel *)CGBitmapContextGetData(context);

        if (areaType | DYNinePatchStripTypeTop) {
            NSUInteger firstBlackPixel = NSNotFound;
            NSUInteger lastBlackPixel = NSNotFound;
            for (int index = 0; index < width; index ++ ) {
                if (IsBlackPixel(pixelData[width - index - 1])) {
                    firstBlackPixel = width - index - 1;
                }
                if (IsBlackPixel(pixelData[index])) {
                    lastBlackPixel = index;
                }
            }
            // 水平拉伸区域
            left = firstBlackPixel;
            right = lastBlackPixel;
        }
        
        if (areaType | DYNinePatchStripTypeLeft) {
            NSUInteger firstBlackPixel = NSNotFound;
            NSUInteger lastBlackPixel = NSNotFound;
            for (int index = 0; index < height; index ++ ) {
                if (IsBlackPixel(pixelData[(height - index - 1)  * width])) {
                    firstBlackPixel = (height - index - 1);
                }
                if (IsBlackPixel(pixelData[index * width])) {
                    lastBlackPixel = index;
                }
            }
            // 垂直拉伸区域
            top = firstBlackPixel;
            bottom = lastBlackPixel;
        }
        
        if (areaType | DYNinePatchStripTypeBottom) {
            NSUInteger firstBlackPixel = NSNotFound;
            NSUInteger lastBlackPixel = NSNotFound;
            for (int index = 0; index < width; index ++ ) {
                if (IsBlackPixel(pixelData[(height - 1) * width + width - index - 1])) {
                    firstBlackPixel =  width - index - 1;
                }
                if (IsBlackPixel(pixelData[(height - 1) * width + index])) {
                    lastBlackPixel = index;
                }
            }
            // 水平展示区域
            c_left = firstBlackPixel;
            c_right = lastBlackPixel;
        }
        
        if (areaType | DYNinePatchStripTypeRight) {
            NSUInteger firstBlackPixel = NSNotFound;
            NSUInteger lastBlackPixel = NSNotFound;
            for (int index = 0; index < height; index ++ ) {
                if (IsBlackPixel(pixelData[(height - index)  * width - 1])) {
                    firstBlackPixel = (height - index - 1);
                }
                if (IsBlackPixel(pixelData[index * width - 1])) {
                    lastBlackPixel = index;
                }
            }
            // 垂直展示区域
            c_top = firstBlackPixel;
            c_bottom = lastBlackPixel;
        }
        CGContextRelease(context);
        CGColorSpaceRelease(colorSpace);
        free(pixelByteData);
        
        // 数据整理输出
        if (top > 0 || left > 0 || bottom > 0 || right > 0) {
            // 可拉伸，上左裁剪1px
            CGPoint origin = CGPointMake(1, 1);
            CGSize size = CGSizeMake(width - 1, height - 1);
            top -- ;
            left -- ;
            bottom -- ;
            right -- ;
            
            // 拉伸区域是必选，显示区域是可选的
            if (c_top > 0 || c_left > 0 || c_bottom > 0 || c_right > 0) {
                // 有可选的内容限定区域，下右多裁剪1px
                size = CGSizeMake(width - 2, height - 2);
            }
            
            *cropFrame = CGRectMake(origin.x, origin.y, size.width, size.height);
            *resizableInset = UIEdgeInsetsMake(top, left, bottom, right);
            *contentInset = UIEdgeInsetsMake(c_top, c_left, c_bottom, c_right);
            
            return YES;
        }
    }
    return NO;
}

#pragma mark - 图片裁剪
- (UIImage *)cropImageInRect:(CGRect)frame
{
    UIImage *cropImage = nil;
    CGImageRef cgImage = [self CGImage];
    if (cgImage) {
        CGImageRef cropCGImage = CGImageCreateWithImageInRect(cgImage, frame);
        if (cropCGImage) {
            cropImage = [UIImage imageWithCGImage:cropCGImage scale:self.scale orientation:self.imageOrientation];
            CGImageRelease(cropCGImage);
        }
    }
    return cropImage;
}

#pragma mark - public

- (UIImage *)resizableImage
{
    UIEdgeInsets resizableInset = UIEdgeInsetsZero;
    UIEdgeInsets contentInset = UIEdgeInsetsZero;
    CGRect cropFrame = CGRectZero;
    BOOL result = [self searchBlackStrip:DYNinePatchStripTypeAll resizableInset:&resizableInset contentInset:&contentInset cropFrame:&cropFrame];
    if (!result) {
        NSLog(@"不是点九图");
        return nil;
    }
    NSLog(@"搜索完毕 拉伸区域:%@ 显示区域：%@ 裁剪区域：%@", NSStringFromUIEdgeInsets(resizableInset), NSStringFromUIEdgeInsets(contentInset), NSStringFromCGRect(cropFrame));
    UIImage *cropImage = [self cropImageInRect:cropFrame];
    return [cropImage resizableImageWithCapInsets:resizableInset resizingMode:UIImageResizingModeTile];
}

@end
